home *** CD-ROM | disk | FTP | other *** search
- #ifndef __THREADS__
- #define __THREADS__
-
- /*
- // by undefining inline, this C++ source can be compiled with no modifications
- // well...maybe
- */
- #define inline
-
- /* Copyright © 1989-91 by Apple Computer, Inc. All rights reserved. */
-
- #ifndef Types_h
- #include <Types.h>
- #endif
-
- #define kDefaultStackSize 1024
-
- #define kUsesFPU 1
- #define kMainThreadHasPriority 2
- #define kDreamEveryTick 4
-
- /* Thread errors: */
-
- #define threadsNotInitedErr -2700
- #define badThreadErr -2701
- #define threadsNotAvailableErr -2702
- #define wrongThreadsVersErr -2702
- #define badSemaphoreErr -2703
- #define threadQueueNotEmptyErr -2704
- #define badSwapSelectorErr -2705
- #define noOtherThreadsToRunErr -2706
- #define kSemaphoreNotFoundErr -2712
-
- /* Customizable swapping behavior instalation selectors: */
-
- #define kCopyContextSel 'cctx'
- #define kSwapInSel 'swpi'
- #define kSwapOutSel 'swpo'
- #define kFreeThreadSel 'tfre'
- #define kScheduleSel 'schd'
- #define kPreYieldSel 'prey'
- #define kPostYieldSel 'post'
-
- /* Each thing can be a member of a list, and can also contain a list of other things. */
-
- typedef struct Thing** ThingHandle;
- typedef struct Thing* ThingPtr;
-
- struct Thing
- {
- ThingHandle fQueue; /* the containing “Thing list” this thing is on */
- ThingHandle fNext; /* the next thing in the list relative to this thing */
- ThingHandle fPrev; /* the previous thing in the list relative to this thing */
- ThingHandle fHead; /* the first thing in the list of things owned by this thing */
- ThingHandle fTail; /* the last thing in the list of things owned by this thing */
- };
-
-
-
-
-
- typedef struct Thread** ThreadHandle;
- typedef struct ThreadQueue** ThreadQueueHandle;
- typedef struct Semaphore** SemaphoreHandle;
- typedef struct Thread* ThreadPtr;
- typedef struct ThreadQueue* ThreadQueuePtr;
-
- /*
- // Think C does not handle Pascal procedures very well.
- // The CallPascal() function must be used.
- */
- #ifdef THINK_C
- typedef OSErr (*ThreadProc)(ThreadHandle);
- typedef void (*SpawnProc)(ThreadHandle,long);
- typedef ThreadHandle (*ScheduleProc)(ThreadHandle);
- typedef Boolean (*ThreadIterProc)(ThreadHandle, void*);
- typedef Boolean (*ThingIterProc)(ThingHandle, void*);
- #else
- typedef pascal OSErr (*ThreadProc)(ThreadHandle);
- typedef pascal void (*SpawnProc)(ThreadHandle,long);
- typedef pascal ThreadHandle (*ScheduleProc)(ThreadHandle);
- typedef pascal Boolean (*ThreadIterProc)(ThreadHandle, void*);
- typedef pascal Boolean (*ThingIterProc)(ThingHandle, void*);
- #endif
-
- extern OSErr gThreadError;
-
-
-
- typedef long ThreadType;
-
- #define StackCopy 0
- /*const ThreadType HeapStack = ; unimplemented */
-
- struct ThreadProcTbl
- {
- ThreadProc fCopyContext; /* copy current context - store in fStack */
- ThreadProc fSwapIn; /* called to context switch "this" thread in */
- ThreadProc fSwapOut; /* calls fSchedule then fSwapIn on the nextThread */
- ThreadProc fFree; /* called to dispose of the Thread */
- ScheduleProc fSchedule; /* queue this thread (if necessary), return the next one */
- ThreadProc fPreYield;
- ThreadProc fPostYield;
- };
-
- typedef struct ThreadProcTbl ThreadProcTbl;
-
- typedef long ThreadState;
-
- #define running 0 /* the Thread is the active context */
- #define pending 1 /* the Thread is awaiting scheduleing (ie. on gPendingQueue) */
- #define blocked 2 /* the Thread is on a semaphore */
- #define sleeping 3 /* the Thread is not blocked or pending */
- #define ended 4 /* the Thread is about to be free'd */
-
-
- #define kNumberOfUserLongs 8
- #define kNumberOfInternalLongs 4
-
- struct Thread
- {
- struct Thing fThing; /* linked list for queue thread is on */
-
- ThreadHandle fNext; /* linked list of all threads */
- ThreadHandle fPrev;
-
- long fUserBytes[kNumberOfUserLongs]; /* for user use */
-
- void* fInternalUse; /* used to keep track of internal globals */
- long fThreadIdentifier; /* used for error checking */
-
- ThreadProc fDream; /* idle proc that gets called for each thread when LetThreadsDream is called */
-
- /*
- // Do not change the order of any fields above this line.
- // Do not depend on any of the items below this line outside
- // of the threads package.
- */
-
- ThreadProcTbl fThreadProcs; /* customizable routines */
-
- ThreadType fType;
- ThreadState fState;
- Boolean fLocked; /* if the ThreadHandle and fStack are Locked - avoids copious calls to HLock/Hunlock */
- Handle fStack; /* the storage for the stack data - if ThreadType == HeapStack this is HLock'ed */
-
- /*
- // Current use of internalBytes:
- //
- // SleepForNTicks: 0 saves dreamProc, 1 saves sleep len, 2 saves sleep start time
- //
- // Launcher: 3 saves handle to launch info stuff
- */
- long fInternalBytes[kNumberOfInternalLongs]; /* for internal use */
- };
-
- typedef struct Thread Thread;
-
- /* manager routines: */
-
- pascal OSErr InitThreads( short threadFlags );
- pascal OSErr ThreadError(void);
- pascal ThreadProc InstallSwapProc( long selector, ThreadProc newSwap );
- pascal OSErr RegisterContextGlobal( long* theGlobal );
- pascal OSErr SetMainThread( ThreadHandle mainThread );
- pascal ThreadHandle GetCurrentThread(void);
- pascal ThreadHandle GetMainThread(void);
- pascal void Yield(void);
- pascal void ExitThreads(void); /* while gPendingQueue is not empty Yield */
-
- /* thread routines: */
-
- pascal ThreadHandle NewThread(long stackSize /* ThreadType t */);
- pascal OSErr StartThread(ThreadHandle theThread); /* call fCopy proc and Wake */
- pascal Boolean InThread(ThreadHandle theThread); /* true if theThread is running */
- pascal Boolean InMainThread(void); /* true if mainThread is running */
- pascal OSErr Sleep(ThreadHandle theThread); /* remove form gPendingQueue (or swap out if running) place on gSleepingQueue */
- pascal OSErr SleepForNTicks(ThreadHandle theThread, long sleepTime); /* like sleep, but wake up after N ticks */
- pascal OSErr Wake(ThreadHandle theThread); /* place on gPendingQueue */
- pascal OSErr EndThread(ThreadHandle theThread); /* call fFree - never returns, end of context */
-
- /* convienence routines: */
-
- pascal Boolean InNewThread(ThreadHandle* theThread, long stackSize); /* NewThread, StartThread, InThread */
- pascal ThreadHandle Spawn(ThreadHandle, SpawnProc spawnProc, long stackSize, long refcon);
-
-
- /* default methods: */
-
- pascal void TCopyContext(ThreadHandle); /* copy the current context */
- pascal void TSwapIn(ThreadHandle); /* make this thread's context the active context */
- pascal void TSwapOut(ThreadHandle); /* save the current context (or free the thread if fState == ended) */
- pascal void TFree(ThreadHandle); /* dispose of the thread */
- pascal ThreadHandle TSchedule(ThreadHandle); /* returns the next thread to be run, queue this thread is necessary */
-
- /* thing routines */
-
- pascal void IThing(ThingHandle);
-
- pascal void ThingInsertLast(ThingHandle queue, ThingHandle thing);
- pascal ThingHandle ThingTakeFirst(ThingHandle);
- pascal ThingHandle ThingGetFirst(ThingHandle);
- pascal void ThingRemove(ThingHandle thing);
-
- pascal ThingHandle ThingOwner(ThingHandle); /* return the queue this thing is on */
- pascal Boolean ThingIsEmpty(ThingHandle); /* indicate whether or not this thing contains one or more things */
-
- pascal void ThingEach( ThingHandle q, ThingIterProc proc, void* refCon );
-
- pascal void FreeThing(ThingHandle); /* lets go of contained things, but does not free them, then frees self */
-
-
- /* dreaming support */
-
- pascal void ThreadEach( ThreadIterProc proc, void* refCon );
- pascal void LetThreadsDream(void);
-
- /* semaphores: */
-
- struct Semaphore
- {
- struct Thing fThing;
- long fCount;
- long fSemaphoreGID;
-
- SemaphoreHandle fNext;
- SemaphoreHandle fPrev;
-
- long fSemaphoreIdentifier;
- };
-
- typedef struct Semaphore Semaphore;
-
- pascal SemaphoreHandle NewSemaphore(void);
- pascal void BlockOnSemaphore(SemaphoreHandle, ThreadHandle);
- pascal void ReleaseOneThread(SemaphoreHandle);
- pascal void ReleaseAllThreads(SemaphoreHandle);
- pascal void FreeSemaphore(SemaphoreHandle);
-
- pascal void GrabSemaphore(SemaphoreHandle);
- pascal void ReleaseSemaphore(SemaphoreHandle);
-
- pascal SemaphoreHandle LookupSemaphore( long semaphoreGID );
-
-
- #endif